from django.http import HttpResponse
from django.shortcuts import render
from One2Many.models import UserType, User


# Create One2Many views here.


# 一对多关系
# 添加用户类型数据
def add_user_type(request):
    # 给UserType添加数据
    user_types = ['青铜', '白银', '黄金', '钻石', '大师', '王者']
    for name in user_types:
        UserType.objects.create(name=name)

    return HttpResponse('添加用户类型成功！')


# 添加用户数据
def add_user(request):

    # 给User添加数据
    for i in range(11, 30):
        # 方式一：添加时使用外键id来添加
        User.objects.create(name=f'小{i}子', age=i, user_type_id=i % 6 + 1)
        # 方式二：添加时使用对象
        user_type_obj = UserType.objects.get(pk=i % 6 + 1)
        User.objects.create(name=f'大{i}瓜', age=i, user_type=user_type_obj)

    return HttpResponse('添加用户成功！')


# 删除用户数据
def del_user(request):
    # 删除用户数据
    User.objects.filter(id=6).delete()
    return HttpResponse('删除用户成功！')


# 删除用户类型数据
def del_user_type(request):
    # 删除用户类型是要注意的，因为这个用户类型下面会有用户关联
    # 可以在创建model的时候在外键中设置on_delete模式
    """
        删除操作可以在定义外键关系的时候，通过on_delete参数来配置删除时做的操作。
        on_delete参数主要有以下几个可选值：
        models.CASCADE  级联删除，即删除UserType时，相关联的UserInfo也会被删除。
        models.PROTECT  保护模式，阻止级联删除。
        models.SET_NULL 置空模式，设置null。null=True参数必须具备
        models.SET_DEFAULT 置默认值，设置默认值，default参数必须具备
        models.SET()    删除的时候重新动态只想一个实体访问对应元素，可以传入函数
        models.DO_NOTHING 什么也不做。
        注意：修改on_delete参数之后需要重新同步数据库，生成迁移文件执行迁移。
    """
    # UserType.objects.get(id=6).delete()
    # UserType.objects.get(id=5).delete()  # 在保护模式下删除会报错ProtectedError
    # UserType.objects.get(id=4).delete()  # 置默认值模式下，属于4的类型会变成我设置的默认值1
    UserType.objects.get(id=3).delete()  # 什么都不做会报错，这种模式不建议使用 FOREIGN KEY constraint failed
    return HttpResponse('删除用户类型成功！')


# 修改用户数据
def update_user(request):
    # 修改用户数据不会影响所关联的用户类型
    User.objects.filter(id=3).update(age=99)

    return HttpResponse('修改用户数据成功！')


# 修改用户类型
def update_user_type(request):
    # 修改用户类型数据不会影响用户数据
    UserType.objects.filter(id=1).update(name='钻石')

    return HttpResponse('修改用户类型数据成功！')


# 查询操作
def get_user(request):

    # 正向查询
    # 意思是从有定义外键的表查找被关联表
    # 查询id为2的用户，他所属的用户类型的名称和id
    user = User.objects.get(id=3)
    print(user.name, user.age, user.user_type, user.user_type_id)
    print(user.user_type.id, user.user_type.name)

    # 反向查询
    # 意思是从被关联的表出发去查询定义了外键的表
    utype = UserType.objects.get(id=1)
    print(utype.id, utype.name)
    # 查询id为1的用户类型的所有用户
    print(utype.user_set)   # ‘模型小写名称_set’是一个管理对象
    print(utype.user_set.all())  # 查询集

    # 在filter中还可以如下方式使用
    # 比如：查找用户类型为白银的所有用户
    # 方法一
    users = User.objects.filter(user_type=UserType.objects.get(name='白银'))
    print(users)
    # 方法二
    users = User.objects.filter(user_type_id=2)
    print(users)
    # 方法三（重点）
    users = User.objects.filter(user_type__name='白银')
    print(users)

    # related_name
    utype = UserType.objects.get(id=1)
    utype.user_set.all()  # 没设置之前默认是这种方式
    # utype.users.all()   # 设置后用你自己设置的名字related_name='users'

    return HttpResponse('查询成功！')
